import {
  EventType,
  EventHandler,
  CellPosition,
  CellRange,
  CellClickEvent,
  CellChangeEvent,
  SelectionChangeEvent,
  Column,
  DataType,
  SelectionMode
} from '../types'
import { VirtualScrollManager } from '../virtual-scroll/VirtualScrollManager'
import { DataManager } from '../data/DataManager'
import { EditorFactory } from '../editors/EditorFactory'

export class EventManager {
  private canvas: HTMLCanvasElement
  private scrollManager: VirtualScrollManager
  private dataManager: DataManager
  private eventHandlers: Map<EventType, Set<EventHandler>> = new Map()
  
  // 鼠标状态
  private isDragging: boolean = false
  private isScrollbarDragging: boolean = false
  private scrollbarType: 'vertical' | 'horizontal' | null = null
  private dragStartPos: { x: number; y: number } | null = null
  private dragStartCell: CellPosition | null = null
  
  // 填充柄状态
  private isFillHandleDragging: boolean = false
  private fillHandleStart: CellPosition | null = null
  private fillHandleEnd: CellPosition | null = null
  
  // 鼠标悬停状态
  private hoveredCell: CellPosition | null = null
  private hoveredRow: number = -1
  private hoveredColumn: number = -1
  
  // 拖拽移动状态
  private isDragMoving: boolean = false
  private dragMoveStart: CellPosition | null = null
  private dragMoveOffset: { x: number; y: number } = { x: 0, y: 0 }
  
  // 鼠标操作模式
  private mouseMode: 'select' | 'fill' | 'move' = 'select'
  
  // 选择状态
  private selectedCell: CellPosition | null = null
  private selectionRange: CellRange | null = null
  private selectedCells: Set<string> = new Set() // 多选的单元格集合
  private isMultiSelect: boolean = false
  
  // 行列选择状态
  private selectedRows: Set<number> = new Set()
  private selectedColumns: Set<number> = new Set()
  private selectionMode: SelectionMode = SelectionMode.Cell
  private lastSelectedRow: number = -1
  private lastSelectedColumn: number = -1
  
  // 编辑状态
  private isEditing: boolean = false
  private editingCell: CellPosition | null = null
  private editor: HTMLElement | null = null
  
  // 键盘导航
  private currentCell: CellPosition = { row: 0, col: 0 }  // 初始值，会在setData时更新
  
  // 列调整
  private isResizingColumn: boolean = false
  private resizingColumn: number = -1
  private resizeStartX: number = 0
  private resizeStartWidth: number = 0
  
  // 行高调整
  private isResizingRow: boolean = false
  private resizingRow: number = -1
  private resizeStartY: number = 0
  private resizeStartHeight: number = 0
  
  // 行高映射（行索引 -> 行高）
  private rowHeights: Map<number, number> = new Map()
  private defaultRowHeight: number = 30
  
  // 配置
  private showRowNumber: boolean = true
  private rowNumberWidth: number = 50
  
  // 剪贴板数据
  private clipboardData: {
    cells: CellPosition[]
    values: Map<string, any>
    isCut: boolean
  } | null = null
  
  // 自动滚动
  private autoScrollTimer: number | null = null
  private autoScrollDirection: { x: number; y: number } = { x: 0, y: 0 }
  
  // 拖拽提示
  private resizeTooltip: HTMLElement | null = null
  
  // 渲染器引用（用于更新滚动条悬停状态）
  private renderer: any = null
  
  // 添加滚动条拖动的起始状态
  private scrollbarDragStart: {
    scrollPosition: number
    mousePosition: number
    thumbPosition: number
  } | null = null
  
  // 渲染相关的优化
  private renderPending: boolean = false
  private lastRenderTime: number = 0
  private renderThrottle: number = 16 // 约60fps
  
  // 滚动条拖动的节流
  private scrollbarDragThrottle: number | null = null
  private pendingScrollbarUpdate: { x: number; y: number } | null = null
  
  // 设置表格实例引用
  private table: any

  constructor(
    canvas: HTMLCanvasElement,
    scrollManager: VirtualScrollManager,
    dataManager: DataManager,
    options?: {
      showRowNumber?: boolean
      rowNumberWidth?: number
    }
  ) {
    this.canvas = canvas
    this.scrollManager = scrollManager
    this.dataManager = dataManager
    this.showRowNumber = options?.showRowNumber ?? true
    this.rowNumberWidth = options?.rowNumberWidth ?? 50
    this.defaultRowHeight = this.scrollManager.getDefaultRowHeight() || 30
    
    // console.log('EventManager 初始化:', {
    //   showRowNumber: this.showRowNumber,
    //   rowNumberWidth: this.rowNumberWidth,
    //   defaultRowHeight: this.defaultRowHeight,
    //   headerHeight: this.scrollManager.getHeaderHeight()
    // })
    
    // // 检查columns是否正确
    // const columns = this.dataManager['columns']
    // console.log('EventManager - 初始化时的列信息:', columns)
    // console.log('EventManager - 列数:', columns?.length || 0)
    
    this.initializeEventListeners()
  }

  // 初始化事件监听
  private initializeEventListeners(): void {
    // 绑定事件
    this.canvas.addEventListener('mousedown', this.handleMouseDown.bind(this))
    this.canvas.addEventListener('mousemove', this.handleMouseMove.bind(this))
    this.canvas.addEventListener('mouseup', this.handleMouseUp.bind(this))
    this.canvas.addEventListener('dblclick', this.handleDoubleClick.bind(this))
    this.canvas.addEventListener('contextmenu', this.handleContextMenu.bind(this))
    this.canvas.addEventListener('keydown', this.handleKeyDown.bind(this))
    this.canvas.addEventListener('wheel', this.handleWheel.bind(this), { passive: false })
    
    // 添加 mouseleave 事件处理，清除悬停状态
    this.canvas.addEventListener('mouseleave', this.handleMouseLeave.bind(this))
    
    // 文档级事件，用于处理鼠标移出画布的情况
    // 注意：这里可能会导致重复处理，需要检查事件目标
    const documentMouseUp = (e: MouseEvent) => {
      // 只有在鼠标真正释放时才处理
      if (this.isResizingRow || this.isResizingColumn || this.isDragging) {
        this.handleMouseUp(e)
      }
    }
    
    const documentMouseMove = (e: MouseEvent) => {
      // 只有在正在拖拽时才处理文档级的鼠标移动
      if (this.isResizingRow || this.isResizingColumn || this.isDragging) {
        this.handleMouseMove(e)
      }
    }
    
    document.addEventListener('mouseup', documentMouseUp)
    document.addEventListener('mousemove', documentMouseMove)
    
    // 保存清理函数
    ;(this as any).documentMouseUp = documentMouseUp
    ;(this as any).documentMouseMove = documentMouseMove
    
    // 确保画布可以接收键盘事件
    this.canvas.tabIndex = 0
    this.canvas.style.outline = 'none'
  }

  // 处理鼠标按下
  private handleMouseDown(e: MouseEvent): void {
    const rect = this.canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    // 检查是否点击在填充柄上
    if (this.isOnFillHandle(x, y)) {
      this.startFillHandleDrag()
      return
    }
    
    // 检查是否点击在滚动条上
    if (this.isOnScrollbar(x, y)) {
      this.startScrollbarDrag(x, y)
      return
    }
    
    // 优先检查是否点击在行边框上（用于调整行高）
    const resizeRow = this.getRowResizeHandle(x, y)
    
    if (resizeRow >= 0) {
      this.startRowResize(resizeRow, y)
      return
    }
    
    // 优先检查是否点击在列边框上（用于调整列宽）
    const resizeColumn = this.getColumnResizeHandle(x, y)
    
    if (resizeColumn >= 0) {
      this.startColumnResize(resizeColumn, x)
      return
    }
    
    // 检查是否点击在左上角（行号列的表头）- 全选
    if (this.showRowNumber && x < this.rowNumberWidth && y < this.scrollManager.getHeaderHeight()) {
      // 全选所有单元格
      this.selectAll()
      
      // 触发选择变化事件
      this.emit(EventType.SelectionChange, {
        selectedCells: this.getSelectedCells(),
        selectedRange: this.selectionRange,
        selectionMode: SelectionMode.Range
      } as SelectionChangeEvent)
      
      this.requestRender()
      return
    }
    
    // 检查是否点击在行号上
    if (this.showRowNumber && x < this.rowNumberWidth && y > this.scrollManager.getHeaderHeight()) {
      const row = this.scrollManager.getRowByY(y)
      if (row >= 0) {
        this.handleRowClick(row, e)
        return
      }
    }
    
    // 检查是否点击在列头上
    if (y < this.scrollManager.getHeaderHeight() && x > (this.showRowNumber ? this.rowNumberWidth : 0)) {
      const adjustedX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
      const col = this.scrollManager.getColumnByX(adjustedX)
      if (col >= 0) {
        this.handleColumnClick(col, e)
        return
      }
    }
    
    // 获取点击的单元格
    const cell = this.getCellByPosition(x, y)
    if (!cell) return
    
    // 处理选择
    if (e.shiftKey && this.selectedCell) {
      // Shift+点击：范围选择
      this.selectionRange = {
        start: this.selectedCell,
        end: cell
      }
      this.selectedCells.clear() // 清除多选
      this.clipboardData = null // 清除剪贴板数据
      this.emit(EventType.SelectionChange, {
        selectedCells: this.getSelectedCells(),
        selectedRange: this.selectionRange
      } as SelectionChangeEvent)
    } else if (e.ctrlKey || e.metaKey) {
      // Ctrl/Cmd+点击：多选
      this.isMultiSelect = true
      const cellKey = `${cell.row},${cell.col}`
      
      if (this.selectedCells.has(cellKey)) {
        // 如果已选中，则取消选中
        this.selectedCells.delete(cellKey)
      } else {
        // 添加到选中集合
        this.selectedCells.add(cellKey)
      }
      
      // 清除范围选择
      this.selectionRange = null
      this.clipboardData = null // 清除剪贴板数据
      
      this.emit(EventType.SelectionChange, {
        selectedCells: this.getSelectedCells(),
        selectedRange: undefined
      } as SelectionChangeEvent)
    } else {
      // 普通点击：单选
      this.selectedCell = cell
      this.currentCell = cell
      this.selectionRange = null
      this.selectedCells.clear()
      this.isMultiSelect = false
      
      // 清除行列选择
      this.selectedRows.clear()
      this.selectedColumns.clear()
      this.selectionMode = SelectionMode.Cell
      
      // 清除剪贴板数据（取消复制/剪切状态）
      this.clipboardData = null
      
      // 先触发选择变化事件，明确指示清除了范围选择
      this.emit(EventType.SelectionChange, {
        selectedCells: this.getSelectedCells(),
        selectedRange: null,  // 使用null而不是undefined
        selectionMode: this.selectionMode
      } as SelectionChangeEvent)
      
      // 再触发单元格点击事件
      this.emit(EventType.CellClick, {
        row: cell.row,
        col: cell.col,
        value: this.getCellValue(cell),
        originalEvent: e
      } as CellClickEvent)
    }
    
    // 开始拖动选择
    this.isDragging = true
    this.dragStartPos = { x, y }
    this.dragStartCell = cell
    
    // 聚焦画布以接收键盘事件
    this.canvas.focus()
  }

  // 处理鼠标移动
  private handleMouseMove(e: MouseEvent): void {
    const rect = this.canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    // 处理滚动条拖动
    if (this.isScrollbarDragging) {
      this.handleScrollbarDrag(x, y)
      return
    }
    
    // 处理列宽调整
    if (this.isResizingColumn) {
      this.handleColumnResize(x)
      return
    }
    
    // 处理行高调整
    if (this.isResizingRow) {
      this.handleRowResize(y)
      return
    }
    
    // 处理填充柄拖拽
    if (this.isFillHandleDragging) {
      this.handleFillHandleDrag(x, y)
      return
    }
    
    // 处理单元格拖拽移动
    if (this.isDragMoving) {
      this.handleDragMove(x, y)
      return
    }
    
    // 更新悬停状态
    this.updateHoverState(x, y)
    
    // 更新鼠标样式
    this.updateCursor(x, y)
    
    // 处理拖动选择
    if (this.isDragging && this.dragStartCell) {
      // 检查拖拽是否从行头开始
      if (this.dragStartPos && this.showRowNumber && this.dragStartPos.x < this.rowNumberWidth) {
        // 从行头开始拖拽，进行行范围选择
        const currentRow = this.scrollManager.getRowByY(y)
        const columns = this.dataManager['columns']
        const colCount = columns.length
        
        if (currentRow >= 0 && this.lastSelectedRow >= 0 && colCount > 0) {
          const start = Math.min(this.lastSelectedRow, currentRow)
          const end = Math.max(this.lastSelectedRow, currentRow)
          
          // 转换为区域选择
          this.selectionRange = {
            start: { row: start, col: 0 },
            end: { row: end, col: colCount - 1 }
          }
          
          // 清除其他选择状态
          this.selectedRows.clear()
          this.selectedCell = null
          this.selectedCells.clear()
          this.selectedColumns.clear()
          this.selectionMode = SelectionMode.Range
          
          // 触发选择变化事件
          this.emit(EventType.SelectionChange, {
            selectedCells: this.getSelectedCells(),
            selectedRange: this.selectionRange,
            selectedRows: [],
            selectedColumns: [],
            selectionMode: this.selectionMode
          } as SelectionChangeEvent)
          
          // 自动滚动
          this.checkAutoScroll(x, y)
        }
      } 
      // 检查拖拽是否从列头开始
      else if (this.dragStartPos && y < this.scrollManager.getHeaderHeight()) {
        // 从列头开始拖拽，进行列范围选择
        const adjustedX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
        const currentCol = this.scrollManager.getColumnByX(adjustedX)
        const rowCount = this.dataManager.getRowCount()
        
        if (currentCol >= 0 && this.lastSelectedColumn >= 0 && rowCount > 0) {
          const start = Math.min(this.lastSelectedColumn, currentCol)
          const end = Math.max(this.lastSelectedColumn, currentCol)
          
          // 转换为区域选择
          this.selectionRange = {
            start: { row: 0, col: start },
            end: { row: rowCount - 1, col: end }
          }
          
          // 清除其他选择状态
          this.selectedColumns.clear()
          this.selectedCell = null
          this.selectedCells.clear()
          this.selectedRows.clear()
          this.selectionMode = SelectionMode.Range
          
          // 触发选择变化事件
          this.emit(EventType.SelectionChange, {
            selectedCells: this.getSelectedCells(),
            selectedRange: this.selectionRange,
            selectedRows: [],
            selectedColumns: [],
            selectionMode: this.selectionMode
          } as SelectionChangeEvent)
          
          // 自动滚动
          this.checkAutoScroll(x, y)
        }
      }
      // 普通单元格拖拽选择
      else {
        const currentCell = this.getCellByPosition(x, y)
        if (currentCell) {
          // 创建或更新范围选择
          this.selectionRange = {
            start: this.dragStartCell,
            end: currentCell
          }
          
          // 清除其他选择状态
          this.selectedCells.clear()
          this.selectedCell = null
          this.selectedRows.clear()
          this.selectedColumns.clear()
          this.selectionMode = SelectionMode.Range
          
          // 触发选择变化事件
          this.emit(EventType.SelectionChange, {
            selectedCells: this.getSelectedCells(),
            selectedRange: this.selectionRange,
            selectionMode: this.selectionMode
          } as SelectionChangeEvent)
        }
        
        // 自动滚动
        this.checkAutoScroll(x, y)
      }
    }
  }

  // 检查并启动自动滚动
  private checkAutoScroll(x: number, y: number): void {
    const scrollZone = 50 // 自动滚动区域大小（增大到50像素）
    const scrollSpeed = 15 // 增加滚动速度
    
    this.autoScrollDirection = { x: 0, y: 0 }
    
    // 检查垂直滚动
    const headerHeight = this.scrollManager.getHeaderHeight()
    if (y < headerHeight + scrollZone && y > headerHeight) {
      // 向上滚动，越接近边缘速度越快
      const ratio = 1 - (y - headerHeight) / scrollZone
      this.autoScrollDirection.y = -scrollSpeed * ratio
    } else if (y > this.canvas.height - scrollZone) {
      // 向下滚动，越接近边缘速度越快
      const ratio = (y - (this.canvas.height - scrollZone)) / scrollZone
      this.autoScrollDirection.y = scrollSpeed * ratio
    }
    
    // 检查水平滚动
    const rowNumberOffset = this.showRowNumber ? this.rowNumberWidth : 0
    if (x < rowNumberOffset + scrollZone && x > rowNumberOffset) {
      // 向左滚动
      const ratio = 1 - (x - rowNumberOffset) / scrollZone
      this.autoScrollDirection.x = -scrollSpeed * ratio
    } else if (x > this.canvas.width - scrollZone) {
      // 向右滚动
      const ratio = (x - (this.canvas.width - scrollZone)) / scrollZone
      this.autoScrollDirection.x = scrollSpeed * ratio
    }
    
    // 启动或停止自动滚动
    if (this.autoScrollDirection.x !== 0 || this.autoScrollDirection.y !== 0) {
      if (!this.autoScrollTimer) {
        this.startAutoScroll()
      }
    } else {
      this.stopAutoScroll()
    }
  }
  
  // 启动自动滚动
  private startAutoScroll(): void {
    // 保存当前鼠标位置
    let lastMouseX = 0
    let lastMouseY = 0
    
    const handleMouseMove = (e: MouseEvent) => {
      lastMouseX = e.clientX
      lastMouseY = e.clientY
    }
    
    // 监听鼠标移动以获取最新位置
    document.addEventListener('mousemove', handleMouseMove)
    
    this.autoScrollTimer = window.setInterval(() => {
      const pos = this.scrollManager.getScrollPosition()
      this.scrollManager.setScrollPosition(
        pos.scrollLeft + this.autoScrollDirection.x,
        pos.scrollTop + this.autoScrollDirection.y
      )
      this.requestRender()
      
      // 更新选择范围，使用实际的鼠标位置
      if (this.isDragging && this.dragStartCell && lastMouseX && lastMouseY) {
        const rect = this.canvas.getBoundingClientRect()
        const x = lastMouseX - rect.left
        const y = lastMouseY - rect.top
        
        const currentCell = this.getCellByPosition(x, y)
        if (currentCell) {
          this.selectionRange = {
            start: this.dragStartCell,
            end: currentCell
          }
          
          this.emit(EventType.SelectionChange, {
            selectedCells: this.getSelectedCells(),
            selectedRange: this.selectionRange,
            selectionMode: this.selectionMode
          } as SelectionChangeEvent)
        }
      }
    }, 16) // 约60fps
    
    // 保存清理函数
    ;(this as any).autoScrollCleanup = () => {
      document.removeEventListener('mousemove', handleMouseMove)
    }
  }
  
  // 停止自动滚动
  private stopAutoScroll(): void {
    if (this.autoScrollTimer) {
      window.clearInterval(this.autoScrollTimer)
      this.autoScrollTimer = null
    }
    
    // 清理事件监听器
    if ((this as any).autoScrollCleanup) {
      (this as any).autoScrollCleanup()
      delete (this as any).autoScrollCleanup
    }
  }

  // 处理鼠标释放
  private handleMouseUp(e: MouseEvent): void {
    // 清理滚动条拖动的节流定时器
    if (this.scrollbarDragThrottle) {
      clearTimeout(this.scrollbarDragThrottle)
      this.scrollbarDragThrottle = null
    }
    this.pendingScrollbarUpdate = null
    
    // 处理填充柄拖拽结束
    if (this.isFillHandleDragging && this.fillHandleStart && this.fillHandleEnd) {
      const direction = this.getFillDirection(this.fillHandleStart, this.fillHandleEnd)
      
      // 创建填充范围
      const fillRange = {
        start: {
          row: Math.min(this.fillHandleStart.row, this.fillHandleEnd.row),
          col: Math.min(this.fillHandleStart.col, this.fillHandleEnd.col)
        },
        end: {
          row: Math.max(this.fillHandleStart.row, this.fillHandleEnd.row),
          col: Math.max(this.fillHandleStart.col, this.fillHandleEnd.col)
        }
      }
      
      // 执行填充操作
      if (fillRange.start.row !== fillRange.end.row || fillRange.start.col !== fillRange.end.col) {
        this.emit('fill-handle-complete' as EventType, {
          range: fillRange,
          direction: direction
        })
      }
    }
    
    // 重置所有拖拽状态
    this.isDragging = false
    this.isScrollbarDragging = false
    this.isResizingColumn = false
    this.isResizingRow = false
    this.isFillHandleDragging = false
    this.isDragMoving = false
    this.dragStartPos = null
    this.dragStartCell = null
    this.scrollbarType = null
    this.scrollbarDragStart = null  // 重置滚动条拖动状态
    this.fillHandleStart = null
    this.fillHandleEnd = null
    this.dragMoveStart = null
    this.resizingRow = -1
    this.resizingColumn = -1
    this.stopAutoScroll()
    
    // 隐藏调整大小提示框
    this.hideResizeTooltip()
    
    // 恢复默认鼠标样式
    this.updateCursor(e.clientX - this.canvas.getBoundingClientRect().left,
                     e.clientY - this.canvas.getBoundingClientRect().top)
  }

  // 处理鼠标离开
  private handleMouseLeave(e: MouseEvent): void {
    // 清除悬停状态
    this.hoveredCell = null
    this.hoveredRow = -1
    this.hoveredColumn = -1
    
    // 隐藏调整大小提示框
    this.hideResizeTooltip()
    
    // 通知渲染器清除悬停状态
    this.emit('hover-change' as EventType, {
      hoveredCell: null,
      hoveredRow: -1,
      hoveredColumn: -1
    })
    
    // 如果正在拖拽或调整列宽，继续处理
    if (!this.isDragging && !this.isResizingColumn && !this.isFillHandleDragging) {
      // 重置鼠标样式
      this.canvas.style.cursor = 'default'
    }
    
    this.requestRender()
  }

  // 处理双击
  private handleDoubleClick(e: MouseEvent): void {
    const rect = this.canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    // 检查是否双击在列边界上（自动调整列宽）
    const resizeColumn = this.getColumnResizeHandle(x, y)
    if (resizeColumn >= 0) {
      this.autoFitColumn(resizeColumn)
      return
    }
    
    const cell = this.getCellByPosition(x, y)
    if (!cell) return
    
    this.emit(EventType.CellDoubleClick, {
      row: cell.row,
      col: cell.col,
      value: this.getCellValue(cell),
      originalEvent: e
    })
    
    // 开始编辑
    this.startEdit(cell)
  }

  // 处理右键菜单
  private handleContextMenu(e: MouseEvent): void {
    e.preventDefault()
    
    const rect = this.canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    // 检查是否在列头上右击
    if (y < this.scrollManager.getHeaderHeight() && x > (this.showRowNumber ? this.rowNumberWidth : 0)) {
      const adjustedX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
      const col = this.scrollManager.getColumnByX(adjustedX)
      
      if (col >= 0) {
        const columns = this.dataManager['columns']
        const column = columns[col]
        
        // 触发列头右键菜单事件
        this.emit(EventType.ContextMenu, {
          type: 'column-header',
          col: col,
          column: column,
          x: e.clientX,
          y: e.clientY,
          originalEvent: e
        })
        return
      }
    }
    
    const cell = this.getCellByPosition(x, y)
    if (!cell) {
      return
    }
    
    // 如果右键点击的单元格不在选择区域内，则选中该单元格
    if (!this.isCellSelected(cell)) {
      this.selectedCell = cell
      this.currentCell = cell
      this.selectionRange = null
      this.selectedCells.clear()
      this.isMultiSelect = false
      this.requestRender()
    }
    
    this.emit(EventType.ContextMenu, {
      type: 'cell',
      row: cell.row,
      col: cell.col,
      x: e.clientX,
      y: e.clientY,
      selectedCells: this.getSelectedCells(),
      originalEvent: e
    })
  }

  // 检查单元格是否被选中
  private isCellSelected(cell: CellPosition): boolean {
    // 检查多选
    if (this.selectedCells.has(`${cell.row},${cell.col}`)) {
      return true
    }
    
    // 检查范围选择
    if (this.selectionRange) {
      const minRow = Math.min(this.selectionRange.start.row, this.selectionRange.end.row)
      const maxRow = Math.max(this.selectionRange.start.row, this.selectionRange.end.row)
      const minCol = Math.min(this.selectionRange.start.col, this.selectionRange.end.col)
      const maxCol = Math.max(this.selectionRange.start.col, this.selectionRange.end.col)
      
      return cell.row >= minRow && cell.row <= maxRow && cell.col >= minCol && cell.col <= maxCol
    }
    
    // 检查单选
    if (this.selectedCell) {
      return cell.row === this.selectedCell.row && cell.col === this.selectedCell.col
    }
    
    return false
  }

  // 辅助方法

  // 检查是否在填充柄上
  private isOnFillHandle(x: number, y: number): boolean {
    if (!this.currentCell) return false
    
    const columns = this.dataManager['columns']
    
    // 检查列索引是否有效
    if (this.currentCell.col < 0 || this.currentCell.col >= columns.length) {
      return false
    }
    
    const column = columns[this.currentCell.col]
    if (!column) return false
    
    // 双重检查 column 的有效性
    if (!column || typeof column !== 'object') {
      console.warn('Invalid column object at index', this.currentCell.col)
      return false
    }
    
    // 使用 try-catch 确保安全访问
    try {
      const cellX = this.scrollManager.getColumnX(this.currentCell.col) + (this.showRowNumber ? this.rowNumberWidth : 0)
      const cellY = this.scrollManager.getRowY(this.currentCell.row)
      const cellWidth = column.width || 100
      const cellHeight = this.scrollManager.getRowHeight(this.currentCell.row)
      
      // 填充柄在右下角，大小为8x8像素
      const handleSize = 8
      const handleX = cellX + cellWidth - handleSize
      const handleY = cellY + cellHeight - handleSize
      
      return x >= handleX && x <= handleX + handleSize &&
             y >= handleY && y <= handleY + handleSize
    } catch (error) {
      console.error('Error in isOnFillHandle:', error)
      return false
    }
  }
  
  // 检查是否在行头上
  private isOnRowHeader(x: number, y: number): boolean {
    return this.showRowNumber && x < this.rowNumberWidth && y > this.scrollManager.getHeaderHeight()
  }
  
  // 检查是否在列头上
  private isOnColumnHeader(x: number, y: number): boolean {
    return y < this.scrollManager.getHeaderHeight() && x > (this.showRowNumber ? this.rowNumberWidth : 0)
  }
  
  // 开始填充柄拖拽
  private startFillHandleDrag(): void {
    this.isFillHandleDragging = true
    this.fillHandleStart = this.currentCell
    this.fillHandleEnd = this.currentCell
    this.canvas.style.cursor = 'crosshair'
  }
  
  // 处理填充柄拖拽
  private handleFillHandleDrag(x: number, y: number): void {
    const cell = this.getCellByPosition(x, y)
    if (!cell) return
    
    this.fillHandleEnd = cell
    
    // 创建填充范围
    if (this.fillHandleStart) {
      const fillRange = {
        start: this.fillHandleStart,
        end: cell
      }
      
      // 触发填充预览
      this.emit('fill-preview' as EventType, {
        range: fillRange,
        direction: this.getFillDirection(this.fillHandleStart, cell)
      })
    }
    
    this.requestRender()
  }
  
  // 获取填充方向
  private getFillDirection(start: CellPosition, end: CellPosition): 'down' | 'up' | 'right' | 'left' {
    const rowDiff = end.row - start.row
    const colDiff = end.col - start.col
    
    if (Math.abs(rowDiff) > Math.abs(colDiff)) {
      return rowDiff > 0 ? 'down' : 'up'
    } else {
      return colDiff > 0 ? 'right' : 'left'
    }
  }

  // 处理拖拽移动
  private handleDragMove(x: number, y: number): void {
    if (!this.dragMoveStart) return
    
    this.dragMoveOffset = {
      x: x - this.dragStartPos!.x,
      y: y - this.dragStartPos!.y
    }
    
    // 触发拖拽预览
    this.emit('drag-preview' as EventType, {
      start: this.dragMoveStart,
      offset: this.dragMoveOffset
    })
    
    this.requestRender()
  }

  // 处理行点击
  private handleRowClick(row: number, e: MouseEvent): void {
    const columns = this.dataManager['columns']
    const colCount = columns.length
    
    if (colCount === 0) return
    
    // 清除之前的选择
    this.selectedCell = null
    this.selectedCells.clear()
    this.selectedRows.clear()
    this.selectedColumns.clear()
    
    if (e.shiftKey && this.lastSelectedRow >= 0) {
      // Shift+点击：扩展行选择范围
      const start = Math.min(this.lastSelectedRow, row)
      const end = Math.max(this.lastSelectedRow, row)
      
      // 转换为区域选择
      this.selectionRange = {
        start: { row: start, col: 0 },
        end: { row: end, col: colCount - 1 }
      }
    } else if (e.ctrlKey || e.metaKey) {
      // Ctrl/Cmd+点击：多行选择
      // 需要特殊处理，因为可能有多个不连续的行
      if (!this.selectedRows.has(row)) {
        this.selectedRows.add(row)
      } else {
        this.selectedRows.delete(row)
      }
      
      // 如果只有一行，转换为区域选择
      if (this.selectedRows.size === 1) {
        const selectedRow = Array.from(this.selectedRows)[0]
        this.selectionRange = {
          start: { row: selectedRow, col: 0 },
          end: { row: selectedRow, col: colCount - 1 }
        }
        this.selectedRows.clear()
      } else if (this.selectedRows.size > 1) {
        // 多行选择保持行选择模式
        this.selectionRange = null
        this.selectionMode = SelectionMode.Row
      } else {
        // 没有选中的行
        this.selectionRange = null
      }
    } else {
      // 普通点击：选中整行（转换为区域选择）
      this.selectionRange = {
        start: { row: row, col: 0 },
        end: { row: row, col: colCount - 1 }
      }
    }
    
    this.lastSelectedRow = row
    this.selectionMode = this.selectedRows.size > 0 ? SelectionMode.Row : SelectionMode.Range
    
    // 触发事件
    this.emit(EventType.RowClick, { row, originalEvent: e })
    this.emit(EventType.SelectionChange, {
      selectedCells: this.getSelectedCells(),
      selectedRange: this.selectionRange,
      selectedRows: Array.from(this.selectedRows),
      selectedColumns: [],
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }
  
  // 处理列点击
  private handleColumnClick(col: number, e: MouseEvent): void {
    const columns = this.dataManager['columns']
    const column = columns[col]
    const rowCount = this.dataManager.getRowCount()
    
    if (rowCount === 0) return
    
    // 清除之前的选择
    this.selectedCell = null
    this.selectedCells.clear()
    this.selectedRows.clear()
    
    if (e.shiftKey && this.lastSelectedColumn >= 0) {
      // Shift+点击：扩展列选择范围
      const start = Math.min(this.lastSelectedColumn, col)
      const end = Math.max(this.lastSelectedColumn, col)
      
      // 转换为区域选择
      this.selectionRange = {
        start: { row: 0, col: start },
        end: { row: rowCount - 1, col: end }
      }
      this.selectedColumns.clear()
    } else if (e.ctrlKey || e.metaKey) {
      // Ctrl/Cmd+点击：多列选择
      if (!this.selectedColumns.has(col)) {
        this.selectedColumns.add(col)
      } else {
        this.selectedColumns.delete(col)
      }
      
      // 如果只有一列，转换为区域选择
      if (this.selectedColumns.size === 1) {
        const selectedCol = Array.from(this.selectedColumns)[0]
        this.selectionRange = {
          start: { row: 0, col: selectedCol },
          end: { row: rowCount - 1, col: selectedCol }
        }
        this.selectedColumns.clear()
      } else if (this.selectedColumns.size > 1) {
        // 多列选择保持列选择模式
        this.selectionRange = null
        this.selectionMode = SelectionMode.Column
      } else {
        // 没有选中的列
        this.selectionRange = null
      }
    } else {
      // 普通点击：选中整列（转换为区域选择）
      this.selectionRange = {
        start: { row: 0, col: col },
        end: { row: rowCount - 1, col: col }
      }
      this.selectedColumns.clear()
    }
    
    this.lastSelectedColumn = col
    this.selectionMode = this.selectedColumns.size > 0 ? SelectionMode.Column : SelectionMode.Range
    
    // 触发事件
    this.emit(EventType.ColumnClick, { col, originalEvent: e })
    this.emit(EventType.SelectionChange, {
      selectedCells: this.getSelectedCells(),
      selectedRange: this.selectionRange,
      selectedRows: [],
      selectedColumns: Array.from(this.selectedColumns),
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }

  // 根据坐标获取单元格
  private getCellByPosition(x: number, y: number): CellPosition | null {
    // 考虑行号列的偏移
    const adjustedX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
    
    const row = this.scrollManager.getRowByY(y)
    const col = this.scrollManager.getColumnByX(adjustedX)
    
    if (row >= 0 && col >= 0) {
      return { row, col }
    }
    
    return null
  }

  // 获取单元格值
  private getCellValue(cell: CellPosition): any {
    try {
      const columns = this.dataManager['columns']
      
      // 检查列索引是否有效
      if (cell.col < 0 || cell.col >= columns.length) {
        return null
      }
      
      const column = columns[cell.col]
      if (!column) return null
      
      // 双重检查 column 的有效性
      if (!column || typeof column !== 'object' || !column.field) {
        console.warn('Invalid column object at getCellValue', cell.col)
        return null
      }
      
      return this.dataManager.getCellValue(cell.row, column.field)
    } catch (error) {
      console.error('Error in getCellValue:', error, cell)
      return null
    }
  }

  // 检查是否在滚动条上
  private isOnScrollbar(x: number, y: number): boolean {
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    
    // 获取画布的逻辑尺寸（不包含 DPR）
    const rect = this.canvas.getBoundingClientRect()
    const canvasWidth = rect.width
    const canvasHeight = rect.height
    
    // 垂直滚动条
    if (scrollbarInfo.vertical.visible && x >= canvasWidth - scrollbarWidth) {
      return true
    }
    
    // 水平滚动条
    if (scrollbarInfo.horizontal.visible && y >= canvasHeight - scrollbarWidth) {
      return true
    }
    
    return false
  }
  
  // 获取滚动条类型
  private getScrollbarType(x: number, y: number): 'vertical' | 'horizontal' | null {
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    
    // 获取画布的逻辑尺寸
    const rect = this.canvas.getBoundingClientRect()
    const canvasWidth = rect.width
    const canvasHeight = rect.height
    
    // 垂直滚动条
    if (scrollbarInfo.vertical.visible && x >= canvasWidth - scrollbarWidth) {
      return 'vertical'
    }
    
    // 水平滚动条
    if (scrollbarInfo.horizontal.visible && y >= canvasHeight - scrollbarWidth) {
      return 'horizontal'
    }
    
    return null
  }

  // 开始滚动条拖动
  private startScrollbarDrag(x: number, y: number): void {
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    
    // 获取画布的逻辑尺寸
    const rect = this.canvas.getBoundingClientRect()
    const canvasWidth = rect.width
    const canvasHeight = rect.height
    
    // 判断是垂直还是水平滚动条
    if (x >= canvasWidth - scrollbarWidth) {
      this.scrollbarType = 'vertical'
      
      // 检查是否点击在滑块上
      const thumbTop = scrollbarInfo.vertical.position
      const thumbBottom = thumbTop + scrollbarInfo.vertical.thumbSize
      
      if (y >= thumbTop && y <= thumbBottom) {
        // 点击在滑块上，记录起始状态
        this.scrollbarDragStart = {
          scrollPosition: this.scrollManager.getScrollPosition().scrollTop,
          mousePosition: y,
          thumbPosition: thumbTop
        }
      } else {
        // 点击在轨道上，跳转到对应位置
        const ratio = y / canvasHeight
        const contentHeight = this.scrollManager.getContentSize().height
        const newScrollTop = ratio * (contentHeight - canvasHeight)
        this.scrollManager.setScrollPosition(newScrollTop, this.scrollManager.getScrollPosition().scrollLeft)
        this.requestRender()
        return
      }
    } else if (y >= canvasHeight - scrollbarWidth) {
      this.scrollbarType = 'horizontal'
      
      // 检查是否点击在滑块上
      const thumbLeft = scrollbarInfo.horizontal.position
      const thumbRight = thumbLeft + scrollbarInfo.horizontal.thumbSize
      
      if (x >= thumbLeft && x <= thumbRight) {
        // 点击在滑块上，记录起始状态
        this.scrollbarDragStart = {
          scrollPosition: this.scrollManager.getScrollPosition().scrollLeft,
          mousePosition: x,
          thumbPosition: thumbLeft
        }
      } else {
        // 点击在轨道上，跳转到对应位置
        const ratio = x / canvasWidth
        const contentWidth = this.scrollManager.getContentSize().width
        const newScrollLeft = ratio * (contentWidth - canvasWidth)
        this.scrollManager.setScrollPosition(this.scrollManager.getScrollPosition().scrollTop, newScrollLeft)
        this.requestRender()
        return
      }
    }
    
    this.isScrollbarDragging = true
  }

  // 处理滚动条拖动
  private handleScrollbarDrag(x: number, y: number): void {
    if (!this.scrollbarType || !this.scrollbarDragStart) return
    
    // 记录待处理的更新
    this.pendingScrollbarUpdate = { x, y }
    
    // 如果已经有节流定时器，直接返回
    if (this.scrollbarDragThrottle) return
    
    // 立即执行一次更新
    this.performScrollbarUpdate()
    
    // 设置节流定时器
    this.scrollbarDragThrottle = window.setTimeout(() => {
      this.scrollbarDragThrottle = null
      // 如果有待处理的更新，执行它
      if (this.pendingScrollbarUpdate) {
        this.performScrollbarUpdate()
      }
    }, 16) // 约60fps
  }
  
  // 执行滚动条更新
  private performScrollbarUpdate(): void {
    if (!this.pendingScrollbarUpdate || !this.scrollbarType || !this.scrollbarDragStart) return
    
    const { x, y } = this.pendingScrollbarUpdate
    this.pendingScrollbarUpdate = null
    
    const rect = this.canvas.getBoundingClientRect()
    const canvasWidth = rect.width
    const canvasHeight = rect.height
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const currentScrollPos = this.scrollManager.getScrollPosition()
    
    if (this.scrollbarType === 'vertical') {
      // 计算鼠标移动的距离
      const mouseDelta = y - this.scrollbarDragStart.mousePosition
      
      // 计算可用的滚动空间
      const maxThumbPosition = canvasHeight - scrollbarInfo.vertical.thumbSize
      
      // 计算新的滑块位置
      const newThumbPosition = Math.max(0, Math.min(maxThumbPosition, this.scrollbarDragStart.thumbPosition + mouseDelta))
      
      // 转换为滚动位置
      const scrollRatio = newThumbPosition / maxThumbPosition
      const contentHeight = this.scrollManager.getContentSize().height
      const maxScrollTop = contentHeight - canvasHeight
      const newScrollTop = scrollRatio * maxScrollTop
      
      this.scrollManager.setScrollPosition(newScrollTop, currentScrollPos.scrollLeft)
    } else {
      // 计算鼠标移动的距离
      const mouseDelta = x - this.scrollbarDragStart.mousePosition
      
      // 计算可用的滚动空间
      const maxThumbPosition = canvasWidth - scrollbarInfo.horizontal.thumbSize
      
      // 计算新的滑块位置
      const newThumbPosition = Math.max(0, Math.min(maxThumbPosition, this.scrollbarDragStart.thumbPosition + mouseDelta))
      
      // 转换为滚动位置
      const scrollRatio = newThumbPosition / maxThumbPosition
      const contentWidth = this.scrollManager.getContentSize().width
      const maxScrollLeft = contentWidth - canvasWidth
      const newScrollLeft = scrollRatio * maxScrollLeft
      
      this.scrollManager.setScrollPosition(currentScrollPos.scrollTop, newScrollLeft)
    }
    
    this.requestRender()
  }

  // 获取列调整手柄
  private getColumnResizeHandle(x: number, y: number): number {
    if (y > this.scrollManager.getHeaderHeight()) {
      return -1
    }
    
    const columns = this.dataManager['columns']
    
    // 检查columns是否有效
    if (!columns || columns.length === 0) {
      return -1
    }
    
    // 考虑行号列的偏移
    const contentX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
    
    // 检查每一列的边界
    for (let i = 0; i < columns.length; i++) {
      // 获取列的左边界位置（已经考虑了滚动）
      const colX = this.scrollManager.getColumnX(i)
      const colWidth = columns[i].width || 100
      const colRightEdge = colX + colWidth
      
      // 检查鼠标是否在列的右边界附近（±3像素）
      if (Math.abs(contentX - colRightEdge) <= 3) {
        return i
      }
      
      // 也检查列的左边界（对于第一列）
      if (i === 0 && Math.abs(contentX - colX) <= 3 && contentX >= -3) {
        return -1 // 第一列的左边界不能调整
      }
    }
    
    return -1
  }

  // 获取行调整手柄
  private getRowResizeHandle(x: number, y: number): number {
    // 只有在行号列才能调整行高
    if (!this.showRowNumber || x > this.rowNumberWidth) {
      return -1
    }
    
    const headerHeight = this.scrollManager.getHeaderHeight()
    if (y <= headerHeight) {
      return -1
    }
    
    // 检查每一行的边界
    const rowCount = this.dataManager.getRowCount()
    for (let row = 0; row < rowCount; row++) {
      // 获取行的顶部位置（已经考虑了滚动）
      const rowY = this.scrollManager.getRowY(row)
      const rowHeight = this.rowHeights.get(row) || this.defaultRowHeight
      const rowBottomEdge = rowY + rowHeight
      
      // 只检查可见范围内的行
      if (rowY > this.canvas.height) {
        break // 后面的行都不可见了
      }
      
      if (rowBottomEdge < headerHeight) {
        continue // 这行在表头下面，不可见
      }
      
      // 检查鼠标是否在行的底边界附近（±3像素）
      if (Math.abs(y - rowBottomEdge) <= 3) {
        return row
      }
    }
    
    return -1
  }

  // 开始列宽调整
  private startColumnResize(column: number, x: number): void {
    const columns = this.dataManager['columns']
    this.isResizingColumn = true
    this.resizingColumn = column
    this.resizeStartX = x
    this.resizeStartWidth = columns[column].width || 100
    
    // 显示初始宽度
    const rect = this.canvas.getBoundingClientRect()
    const y = rect.top + this.scrollManager.getHeaderHeight() / 2
    this.updateResizeTooltip(x, this.scrollManager.getHeaderHeight() / 2, `${Math.round(this.resizeStartWidth)}px`)
  }

  // 处理列宽调整
  private handleColumnResize(x: number): void {
    if (this.resizingColumn < 0) return
    
    const columns = this.dataManager['columns']
    const column = columns[this.resizingColumn]
    const delta = x - this.resizeStartX
    const newWidth = Math.max(30, this.resizeStartWidth + delta) // 最小宽度30
    
    // 检查最大宽度
    const maxWidth = column.maxWidth || 600
    column.width = Math.min(newWidth, maxWidth)
    
    // 更新提示框
    this.updateResizeTooltip(x, this.resizeStartY, `${Math.round(column.width)}px`)
    
    // 更新滚动管理器
    this.scrollManager.setDataInfo(this.dataManager.getRowCount(), columns)
    
    this.emit(EventType.ColumnResize, {
      column: this.resizingColumn,
      width: column.width
    })
    
    this.requestRender()
  }

  // 开始行高调整
  private startRowResize(row: number, y: number): void {
    this.isResizingRow = true
    this.resizingRow = row
    this.resizeStartY = y
    this.resizeStartHeight = this.rowHeights.get(row) || this.defaultRowHeight
    
    // 显示初始高度
    this.updateResizeTooltip(this.rowNumberWidth / 2, y, `${Math.round(this.resizeStartHeight)}px`)
  }
  
  // 处理行高调整
  private handleRowResize(y: number): void {
    if (this.resizingRow < 0) return
    
    const delta = y - this.resizeStartY
    const newHeight = Math.max(20, this.resizeStartHeight + delta) // 最小行高20
    const maxHeight = 200 // 最大行高200
    
    const finalHeight = Math.min(newHeight, maxHeight)
    
    // 更新提示框
    this.updateResizeTooltip(this.rowNumberWidth / 2, y, `${Math.round(finalHeight)}px`)
    
    // 如果行高等于默认值，则从映射中删除
    if (Math.abs(finalHeight - this.defaultRowHeight) < 1) {
      this.rowHeights.delete(this.resizingRow)
    } else {
      this.rowHeights.set(this.resizingRow, finalHeight)
    }
    
    // 更新滚动管理器的行高
    this.scrollManager.setRowHeight(this.resizingRow, finalHeight)
    
    // 触发行高调整事件
    this.emit('row-resize' as EventType, {
      row: this.resizingRow,
      height: finalHeight
    })
    
    this.requestRender()
  }
  
  // 获取行高
  getRowHeight(row: number): number {
    return this.rowHeights.get(row) || this.defaultRowHeight
  }
  
  // 设置行高
  setRowHeight(row: number, height: number): void {
    if (height === this.defaultRowHeight) {
      this.rowHeights.delete(row)
    } else {
      this.rowHeights.set(row, height)
    }
    this.requestRender()
  }
  
  // 重置所有行高
  resetAllRowHeights(): void {
    this.rowHeights.clear()
    this.requestRender()
  }
  
  // 创建调整大小提示框
  private createResizeTooltip(): void {
    if (this.resizeTooltip) return
    
    this.resizeTooltip = document.createElement('div')
    this.resizeTooltip.style.position = 'fixed'
    this.resizeTooltip.style.padding = '4px 8px'
    this.resizeTooltip.style.background = 'rgba(17, 24, 39, 0.9)' // gray-900 with opacity
    this.resizeTooltip.style.color = 'white'
    this.resizeTooltip.style.fontSize = '12px'
    this.resizeTooltip.style.borderRadius = '6px'
    this.resizeTooltip.style.pointerEvents = 'none'
    this.resizeTooltip.style.zIndex = '10000'
    this.resizeTooltip.style.display = 'none'
    this.resizeTooltip.style.fontFamily = 'ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace'
    this.resizeTooltip.style.whiteSpace = 'nowrap'
    this.resizeTooltip.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)'
    document.body.appendChild(this.resizeTooltip)
  }
  
  // 更新调整大小提示框
  private updateResizeTooltip(x: number, y: number, text: string): void {
    if (!this.resizeTooltip) {
      this.createResizeTooltip()
    }
    
    const rect = this.canvas.getBoundingClientRect()
    const tooltipX = rect.left + x + 10
    const tooltipY = rect.top + y - 30
    
    this.resizeTooltip!.style.left = `${tooltipX}px`
    this.resizeTooltip!.style.top = `${tooltipY}px`
    this.resizeTooltip!.textContent = text
    this.resizeTooltip!.style.display = 'block'
  }
  
  // 隐藏调整大小提示框
  private hideResizeTooltip(): void {
    if (this.resizeTooltip) {
      this.resizeTooltip.style.display = 'none'
    }
  }

  // 光标移动
  private moveCursor(rowDelta: number, colDelta: number, extendSelection: boolean = false): void {
    const rowCount = this.dataManager.getRowCount()
    const colCount = this.dataManager.getColumnCount()
    
    // 确保行列索引在有效范围内
    const newRow = Math.max(0, Math.min(this.currentCell.row + rowDelta, rowCount - 1))
    const newCol = Math.max(0, Math.min(this.currentCell.col + colDelta, colCount - 1))
    
    // 如果没有行或列，不执行任何操作
    if (rowCount === 0 || colCount === 0) {
      return
    }
    
    this.currentCell = { row: newRow, col: newCol }
    
    if (extendSelection && this.selectedCell) {
      this.selectionRange = {
        start: this.selectedCell,
        end: this.currentCell
      }
    } else {
      this.selectedCell = this.currentCell
      this.selectionRange = null
    }
    
    // 确保当前单元格可见
    this.scrollManager.scrollToCell(newRow, newCol)
    
    this.emit(EventType.SelectionChange, {
      selectedCells: this.getSelectedCells(),
      selectedRange: this.selectionRange
    } as SelectionChangeEvent)
    
    this.requestRender()
  }

  // 移动到指定位置
  private moveTo(row: number, col: number, extendSelection: boolean = false): void {
    const deltaRow = row - this.currentCell.row
    const deltaCol = col - this.currentCell.col
    this.moveCursor(deltaRow, deltaCol, extendSelection)
  }

  // 向上翻页
  private pageUp(extendSelection: boolean = false): void {
    const rect = this.canvas.getBoundingClientRect()
    const visibleRows = Math.floor((rect.height - this.scrollManager.getHeaderHeight()) / this.scrollManager.getDefaultRowHeight())
    this.moveCursor(-visibleRows, 0, extendSelection)
  }

  // 向下翻页
  private pageDown(extendSelection: boolean = false): void {
    const rect = this.canvas.getBoundingClientRect()
    const visibleRows = Math.floor((rect.height - this.scrollManager.getHeaderHeight()) / this.scrollManager.getDefaultRowHeight())
    this.moveCursor(visibleRows, 0, extendSelection)
  }

  // 全选
  private selectAll(): void {
    this.selectionRange = {
      start: { row: 0, col: 0 },
      end: { row: this.dataManager.getRowCount() - 1, col: this.dataManager.getColumnCount() - 1 }
    }
    
    this.emit(EventType.SelectionChange, {
      selectedCells: this.getSelectedCells(),
      selectedRange: this.selectionRange
    } as SelectionChangeEvent)
    
    this.requestRender()
  }

  // 获取选中的单元格列表
  private getSelectedCells(): CellPosition[] {
    const cells: CellPosition[] = []
    
    // 行选择模式
    if (this.selectionMode === SelectionMode.Row && this.selectedRows.size > 0) {
      const columns = this.dataManager['columns']
      this.selectedRows.forEach(row => {
        for (let col = 0; col < columns.length; col++) {
          cells.push({ row, col })
        }
      })
    }
    // 列选择模式
    else if (this.selectionMode === SelectionMode.Column && this.selectedColumns.size > 0) {
      const rowCount = this.dataManager.getRowCount()
      this.selectedColumns.forEach(col => {
        for (let row = 0; row < rowCount; row++) {
          cells.push({ row, col })
        }
      })
    }
    // 多选模式
    else if (this.selectedCells.size > 0) {
      this.selectedCells.forEach(key => {
        const [row, col] = key.split(',').map(Number)
        cells.push({ row, col })
      })
    }
    // 范围选择模式
    else if (this.selectionRange) {
      const minRow = Math.min(this.selectionRange.start.row, this.selectionRange.end.row)
      const maxRow = Math.max(this.selectionRange.start.row, this.selectionRange.end.row)
      const minCol = Math.min(this.selectionRange.start.col, this.selectionRange.end.col)
      const maxCol = Math.max(this.selectionRange.start.col, this.selectionRange.end.col)
      
      for (let row = minRow; row <= maxRow; row++) {
        for (let col = minCol; col <= maxCol; col++) {
          cells.push({ row, col })
        }
      }
    }
    // 单选模式
    else if (this.selectedCell) {
      cells.push(this.selectedCell)
    }
    
    return cells
  }

  // 开始编辑
  private startEdit(cell: CellPosition): void {
    const columns = this.dataManager['columns']
    const column = columns[cell.col]
    
    if (!column.editable) return
    
    this.isEditing = true
    this.editingCell = cell
    
    // 创建编辑器
    this.createEditor(cell, column)
  }
  
  // 创建编辑器
  private createEditor(cell: CellPosition, column: Column): void {
    // 获取单元格位置和大小
    const cellBounds = this.getCellBounds(cell)
    if (!cellBounds) return
    
    // 创建编辑器容器
    this.editor = document.createElement('div')
    this.editor.className = 'canvas-table-editor'
    this.editor.style.cssText = `
      position: fixed;
      left: ${cellBounds.x}px;
      top: ${cellBounds.y}px;
      width: ${cellBounds.width}px;
      height: ${cellBounds.height}px;
      z-index: 1000;
      box-sizing: border-box;
      overflow: hidden;
    `
    
    // 使用编辑器工厂创建编辑器
    const editorFactory = EditorFactory.getInstance()
    const cellEditor = editorFactory.createEditor(column)
    
    if (!cellEditor) {
      console.error('Failed to create editor for column:', column)
      // 如果创建失败，使用默认的文本编辑器
      const input = document.createElement('input')
      input.type = 'text'
      input.style.width = '100%'
      input.style.height = '100%'
      input.style.border = '2px solid #3b82f6'
      input.style.outline = 'none'
      input.style.padding = '0 8px'
      input.style.fontSize = '13px'
      input.style.fontFamily = 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
      input.style.boxSizing = 'border-box'
      input.style.background = 'white'
      input.style.borderRadius = '4px'
      input.value = String(this.getCellValue(cell) || '')
      
      // 处理输入事件
      input.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' || e.key === 'Tab') {
          e.preventDefault()
          this.endEdit(true)
          if (e.key === 'Tab') {
            this.moveCursor(0, e.shiftKey ? -1 : 1)
          }
        } else if (e.key === 'Escape') {
          e.preventDefault()
          this.endEdit(false)
        }
      })
      
      input.addEventListener('blur', () => {
        this.endEdit(true)
      })
      
      this.editor.appendChild(input)
      document.body.appendChild(this.editor)
      
      // 聚焦并全选
      input.focus()
      input.select()
      return
    }
    
    // 保存编辑器引用
    ;(this as any).currentEditor = cellEditor
    
    // 设置值变化回调（可选）
    cellEditor.onValueChange = (value: any) => {
      // 可以在这里实现实时预览或验证
    }
    
    // 创建编辑器
    const currentValue = this.getCellValue(cell)
    cellEditor.create(this.editor, currentValue, column)
    
    // 添加键盘事件处理
    this.editor.addEventListener('keydown', ((e: Event) => {
      const keyEvent = e as KeyboardEvent
      
      // Enter 键处理
      if (keyEvent.key === 'Enter') {
        // 对于多行文本编辑器，需要 Ctrl/Cmd + Enter 才能结束编辑
        if (column.editType === 'textarea' && !(keyEvent.ctrlKey || keyEvent.metaKey)) {
          return // 允许换行
        }
        keyEvent.preventDefault()
        this.endEdit(true)
      } 
      // Escape 键取消编辑
      else if (keyEvent.key === 'Escape') {
        keyEvent.preventDefault()
        this.endEdit(false)
      } 
      // Tab 键移动到下一个单元格
      else if (keyEvent.key === 'Tab') {
        keyEvent.preventDefault()
        this.endEdit(true)
        // 移动到下一个单元格
        this.moveCursor(0, keyEvent.shiftKey ? -1 : 1)
      }
    }) as EventListener)
    
    // 添加失焦事件处理
    this.editor.addEventListener('focusout', (e) => {
      // 延迟处理，避免与其他事件冲突
      setTimeout(() => {
        // 检查焦点是否还在编辑器内
        if (this.editor && !this.editor.contains(document.activeElement)) {
          this.endEdit(true)
        }
      }, 100)
    })
    
    document.body.appendChild(this.editor)
    
    // 聚焦编辑器
    cellEditor.focus()
  }
  
  // 获取单元格边界
  private getCellBounds(cell: CellPosition): { x: number; y: number; width: number; height: number } | null {
    const viewport = this.scrollManager.getViewport()
    const columns = this.dataManager['columns']
    
    // 检查单元格是否在可见范围内
    if (cell.row < viewport.startRow || cell.row > viewport.endRow) return null
    if (cell.col < viewport.startCol || cell.col > viewport.endCol) return null
    
    // 获取画布相对于视口的位置
    const canvasRect = this.canvas.getBoundingClientRect()
    
    // 使用scrollManager的方法直接获取单元格的实际位置
    const x = this.scrollManager.getColumnX(cell.col) + (this.showRowNumber ? this.rowNumberWidth : 0)
    const y = this.scrollManager.getRowY(cell.row)
    const width = columns[cell.col].width || 100
    const height = this.scrollManager.getRowHeight(cell.row)
    
    // 获取滚动条信息
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    
    // 计算实际的单元格位置
    let cellX = canvasRect.left + x
    let cellY = canvasRect.top + y
    let cellWidth = width
    let cellHeight = height
    
    // 如果单元格会覆盖垂直滚动条，调整宽度
    if (scrollbarInfo.vertical.visible && 
        cellX + cellWidth > canvasRect.right - scrollbarWidth) {
      cellWidth = Math.max(10, canvasRect.right - scrollbarWidth - cellX)
    }
    
    // 如果单元格会覆盖水平滚动条，调整高度
    if (scrollbarInfo.horizontal.visible && 
        cellY + cellHeight > canvasRect.bottom - scrollbarWidth) {
      cellHeight = Math.max(10, canvasRect.bottom - scrollbarWidth - cellY)
    }
    
    // 确保编辑器不会超出画布边界
    cellWidth = Math.max(10, Math.min(cellWidth, canvasRect.right - cellX))
    cellHeight = Math.max(10, Math.min(cellHeight, canvasRect.bottom - cellY))
    
    return {
      x: cellX,
      y: cellY,
      width: cellWidth,
      height: cellHeight
    }
  }

  // 结束编辑
  private endEdit(save: boolean): void {
    if (!this.isEditing || !this.editingCell || !this.editor) return
    
    if (save) {
      const currentEditor = (this as any).currentEditor
      
      if (currentEditor) {
        // 使用新的编辑器系统
        const columns = this.dataManager['columns']
        const column = columns[this.editingCell.col]
        const oldValue = this.getCellValue(this.editingCell)
        
        // 验证值
        const validationResult = currentEditor.validate()
        if (!validationResult.valid) {
          console.error('Validation error:', validationResult.message)
          // TODO: 显示错误提示
          return
        }
        
        // 获取新值
        const newValue = currentEditor.getValue()
        
        // 设置新值
        if (newValue !== oldValue) {
          this.dataManager.setCellValue(this.editingCell.row, column.field, newValue)
          
          // 触发单元格变化事件
          this.emit(EventType.CellChange, {
            row: this.editingCell.row,
            col: this.editingCell.col,
            field: column.field,
            newValue: newValue,
            oldValue: oldValue
          } as CellChangeEvent)
        }
      } else {
        // 兼容旧的文本输入框
        const input = this.editor.querySelector('input')
        if (input) {
          const columns = this.dataManager['columns']
          const column = columns[this.editingCell.col]
          const oldValue = this.getCellValue(this.editingCell)
          const newValue = input.value
          
          // 类型转换
          let value: any = newValue
          if (column.type === DataType.Number) {
            value = newValue === '' ? null : Number(newValue)
          } else if (column.type === DataType.Boolean) {
            value = newValue.toLowerCase() === 'true'
          }
          
          // 设置新值
          this.dataManager.setCellValue(this.editingCell.row, column.field, value)
          
          // 触发单元格变化事件
          this.emit(EventType.CellChange, {
            row: this.editingCell.row,
            col: this.editingCell.col,
            field: column.field,
            newValue: value,
            oldValue: oldValue
          } as CellChangeEvent)
        }
      }
    }
    
    // 销毁编辑器
    const currentEditor = (this as any).currentEditor
    if (currentEditor) {
      currentEditor.destroy()
      ;(this as any).currentEditor = null
    }
    
    // 移除编辑器
    this.editor.remove()
    this.editor = null
    this.isEditing = false
    this.editingCell = null
    
    // 重新聚焦画布
    this.canvas.focus()
    this.requestRender()
  }

  // 删除选中的单元格
  private deleteSelectedCells(): void {
    const cells = this.getSelectedCells()
    const columns = this.dataManager['columns']
    
    cells.forEach(cell => {
      const column = columns[cell.col]
      if (column.editable) {
        const oldValue = this.dataManager.getCellValue(cell.row, column.field)
        this.dataManager.setCellValue(cell.row, column.field, null)
        
        // 触发单元格变化事件
        this.emit(EventType.CellChange, {
          row: cell.row,
          col: cell.col,
          field: column.field,
          oldValue: oldValue,
          newValue: null
        } as CellChangeEvent)
      }
    })
    
    this.emit('data-change' as EventType, null)
    this.requestRender()
  }

  // 复制
  private async copy(): Promise<void> {
    const cells = this.getSelectedCells()
    if (cells.length === 0) return
    
    // 构建剪贴板数据
    const values = new Map<string, any>()
    const columns = this.dataManager['columns']
    
    cells.forEach(cell => {
      const column = columns[cell.col]
      const value = this.dataManager.getCellValue(cell.row, column.field)
      values.set(`${cell.row},${cell.col}`, value)
    })
    
    this.clipboardData = {
      cells: cells,
      values: values,
      isCut: false
    }
    
    // 构建文本数据用于系统剪贴板
    const textData = this.buildClipboardText(cells)
    
    // 复制到系统剪贴板
    try {
      await navigator.clipboard.writeText(textData)
    } catch (err) {
      console.warn('Failed to copy to clipboard:', err)
    }
    
    this.emit(EventType.Copy, {
      cells: cells,
      data: textData
    })
    
    // 触发重新渲染以显示复制边框
    this.requestRender()
  }

  // 粘贴
  private async paste(): Promise<void> {
    try {
      // 从系统剪贴板读取文本
      const text = await navigator.clipboard.readText()
      if (!text) return
      
      // 解析文本数据
      const data = this.parseClipboardText(text)
      if (data.length === 0) return
      
      // 获取粘贴起始位置
      const startCell = this.currentCell
      const columns = this.dataManager['columns']
      
      // 记录所有修改的单元格
      const modifiedCells: Array<{ row: number; col: number; field: string; oldValue: any; newValue: any }> = []
      
      // 计算需要的行数
      const requiredRows = startCell.row + data.length
      const currentRowCount = this.dataManager.getRowCount()
      
      // 如果需要，自动添加新行
      if (requiredRows > currentRowCount) {
        const rowsToAdd = requiredRows - currentRowCount
        console.log(`粘贴操作需要添加 ${rowsToAdd} 行，当前行数: ${currentRowCount}，需要行数: ${requiredRows}`)
        
        for (let i = 0; i < rowsToAdd; i++) {
          // 创建新行数据对象
          const newRowData: any = {}
          columns.forEach(col => {
            newRowData[col.field] = null
          })
          this.dataManager.insertRow(currentRowCount + i, newRowData)
        }
        
        // 更新滚动管理器的数据信息
        const newRowCount = this.dataManager.getRowCount()
        console.log(`新增行后的总行数: ${newRowCount}`)
        this.scrollManager.setDataInfo(newRowCount, columns)
        
        // 触发渲染以确保视图更新
        this.requestRender()
      }
      
      // 粘贴数据
      data.forEach((row, rowIndex) => {
        row.forEach((value, colIndex) => {
          const targetRow = startCell.row + rowIndex
          const targetCol = startCell.col + colIndex
          
          // 检查列边界
          if (targetCol < columns.length) {
            const column = columns[targetCol]
            if (column.editable !== false) {  // 如果没有明确设置为不可编辑，则可以编辑
              // 获取旧值
              const oldValue = this.dataManager.getCellValue(targetRow, column.field)
              
              // 设置新值
              this.dataManager.setCellValue(targetRow, column.field, value)
              
              // 记录修改
              modifiedCells.push({
                row: targetRow,
                col: targetCol,
                field: column.field,
                oldValue: oldValue,
                newValue: value
              })
            }
          }
        })
      })
      
      // 如果是剪切操作，清除原数据
      if (this.clipboardData?.isCut) {
        this.clipboardData.cells.forEach(cell => {
          const column = columns[cell.col]
          if (column.editable !== false) {
            const oldValue = this.dataManager.getCellValue(cell.row, column.field)
            this.dataManager.setCellValue(cell.row, column.field, null)
            
            // 触发单元格变化事件
            this.emit(EventType.CellChange, {
              row: cell.row,
              col: cell.col,
              field: column.field,
              oldValue: oldValue,
              newValue: null
            } as CellChangeEvent)
          }
        })
        this.clipboardData = null
      } else if (this.clipboardData) {
        // 如果是复制操作，粘贴后也清除剪贴板数据
        this.clipboardData = null
      }
      
      // 为每个修改的单元格触发变化事件
      modifiedCells.forEach(cell => {
        this.emit(EventType.CellChange, {
          row: cell.row,
          col: cell.col,
          field: cell.field,
          oldValue: cell.oldValue,
          newValue: cell.newValue
        } as CellChangeEvent)
      })
      
      this.emit(EventType.Paste, {
        targetCell: startCell,
        data: data
      })
      
      this.emit('data-change' as EventType, null)
      this.requestRender()
    } catch (err) {
      console.warn('Failed to paste from clipboard:', err)
      
      // 如果系统剪贴板不可用，使用内部剪贴板数据
      if (this.clipboardData) {
        this.pasteInternalData()
      }
    }
  }
  
  // 粘贴内部数据
  private pasteInternalData(): void {
    if (!this.clipboardData) return
    
    const startCell = this.currentCell
    const columns = this.dataManager['columns']
    
    // 计算偏移量
    const minRow = Math.min(...this.clipboardData.cells.map(c => c.row))
    const minCol = Math.min(...this.clipboardData.cells.map(c => c.col))
    const maxRow = Math.max(...this.clipboardData.cells.map(c => c.row))
    
    // 计算需要的行数
    const requiredRows = startCell.row + (maxRow - minRow + 1)
    const currentRowCount = this.dataManager.getRowCount()
    
    // 如果需要，自动添加新行
    if (requiredRows > currentRowCount) {
      const rowsToAdd = requiredRows - currentRowCount
      console.log(`内部粘贴操作需要添加 ${rowsToAdd} 行，当前行数: ${currentRowCount}，需要行数: ${requiredRows}`)
      
      for (let i = 0; i < rowsToAdd; i++) {
        const newRowData: any = {}
        columns.forEach(col => {
          newRowData[col.field] = null
        })
        this.dataManager.insertRow(currentRowCount + i, newRowData)
      }
      
      // 更新滚动管理器的数据信息
      const newRowCount = this.dataManager.getRowCount()
      console.log(`内部粘贴新增行后的总行数: ${newRowCount}`)
      this.scrollManager.setDataInfo(newRowCount, columns)
      
      // 触发渲染以确保视图更新
      this.requestRender()
    }
    
    // 记录所有修改的单元格
    const modifiedCells: Array<{ row: number; col: number; field: string; oldValue: any; newValue: any }> = []
    
    // 粘贴数据
    this.clipboardData.cells.forEach(cell => {
      const targetRow = startCell.row + (cell.row - minRow)
      const targetCol = startCell.col + (cell.col - minCol)
      
      if (targetCol < columns.length) {
        const column = columns[targetCol]
        if (column.editable !== false) {
          const value = this.clipboardData!.values.get(`${cell.row},${cell.col}`)
          const oldValue = this.dataManager.getCellValue(targetRow, column.field)
          
          this.dataManager.setCellValue(targetRow, column.field, value)
          
          // 记录修改
          modifiedCells.push({
            row: targetRow,
            col: targetCol,
            field: column.field,
            oldValue: oldValue,
            newValue: value
          })
        }
      }
    })
    
    // 如果是剪切操作，清除原数据
    if (this.clipboardData.isCut) {
      this.clipboardData.cells.forEach(cell => {
        const column = columns[cell.col]
        if (column.editable !== false) {
          const oldValue = this.dataManager.getCellValue(cell.row, column.field)
          this.dataManager.setCellValue(cell.row, column.field, null)
          
          // 触发单元格变化事件
          this.emit(EventType.CellChange, {
            row: cell.row,
            col: cell.col,
            field: column.field,
            oldValue: oldValue,
            newValue: null
          } as CellChangeEvent)
        }
      })
      this.clipboardData = null
    } else {
      // 如果是复制操作，粘贴后也清除剪贴板数据
      this.clipboardData = null
    }
    
    // 为每个修改的单元格触发变化事件
    modifiedCells.forEach(cell => {
      this.emit(EventType.CellChange, {
        row: cell.row,
        col: cell.col,
        field: cell.field,
        oldValue: cell.oldValue,
        newValue: cell.newValue
      } as CellChangeEvent)
    })
    
    this.emit('data-change' as EventType, null)
    this.requestRender()
  }
  
  // 构建剪贴板文本
  private buildClipboardText(cells: CellPosition[]): string {
    if (cells.length === 0) return ''
    
    const columns = this.dataManager['columns']
    
    // 获取选择范围
    const minRow = Math.min(...cells.map(c => c.row))
    const maxRow = Math.max(...cells.map(c => c.row))
    const minCol = Math.min(...cells.map(c => c.col))
    const maxCol = Math.max(...cells.map(c => c.col))
    
    // 构建二维数组
    const rows: string[] = []
    for (let row = minRow; row <= maxRow; row++) {
      const rowData: string[] = []
      for (let col = minCol; col <= maxCol; col++) {
        const column = columns[col]
        const value = this.dataManager.getCellValue(row, column.field)
        rowData.push(value === null || value === undefined ? '' : String(value))
      }
      rows.push(rowData.join('\t'))
    }
    
    return rows.join('\n')
  }
  
  // 解析剪贴板文本
  private parseClipboardText(text: string): any[][] {
    const rows = text.split('\n').filter(row => row.length > 0)
    return rows.map(row => {
      return row.split('\t').map(cell => {
        // 去除前后空白
        const trimmedCell = cell.trim()
        
        // 空值返回 null
        if (trimmedCell === '') {
          return null
        }
        
        // 尝试解析布尔值
        if (trimmedCell.toLowerCase() === 'true') return true
        if (trimmedCell.toLowerCase() === 'false') return false
        
        // 检查是否为数字格式（但保持为字符串以避免精度丢失）
        // 支持整数、小数、负数、科学计数法
        const numberPattern = /^-?\d+(\.\d+)?(e[+-]?\d+)?$/i
        if (numberPattern.test(trimmedCell)) {
          // 返回字符串格式的数字，避免精度丢失
          return trimmedCell
        }
        
        // 返回原始字符串
        return cell
      })
    })
  }

  // 剪切
  private async cut(): Promise<void> {
    await this.copy()
    if (this.clipboardData) {
      this.clipboardData.isCut = true
    }
    
    this.emit(EventType.Cut, {
      cells: this.getSelectedCells()
    })
    
    // 触发重新渲染以显示剪切样式
    this.requestRender()
  }

  // 请求重新渲染
  private requestRender(): void {
    // 如果已经有渲染请求在等待，直接返回
    if (this.renderPending) return
    
    // 检查是否需要节流
    const now = performance.now()
    const timeSinceLastRender = now - this.lastRenderTime
    
    if (timeSinceLastRender < this.renderThrottle) {
      // 需要节流，延迟渲染
      this.renderPending = true
      setTimeout(() => {
        this.renderPending = false
        this.performRender()
      }, this.renderThrottle - timeSinceLastRender)
    } else {
      // 可以立即渲染
      this.performRender()
    }
  }
  
  // 执行渲染
  private performRender(): void {
    this.lastRenderTime = performance.now()
    this.renderPending = false
    
    // 使用 requestAnimationFrame 优化性能
    requestAnimationFrame(() => {
      // 触发重绘事件，由外部处理实际的渲染
      this.emit('render' as EventType, null)
    })
  }

  // 事件发射
  private emit(event: EventType | string, data: any): void {
    const handlers = this.eventHandlers.get(event as EventType)
    if (handlers) {
      handlers.forEach(handler => handler(data))
    }
  }

  // 公共方法

  // 添加事件监听
  on(event: EventType, handler: EventHandler): void {
    if (!this.eventHandlers.has(event)) {
      this.eventHandlers.set(event, new Set())
    }
    this.eventHandlers.get(event)!.add(handler)
  }

  // 移除事件监听
  off(event: EventType, handler: EventHandler): void {
    const handlers = this.eventHandlers.get(event)
    if (handlers) {
      handlers.delete(handler)
    }
  }

  // 获取当前选择
  getSelection(): {
    selectedCell: CellPosition | null
    selectionRange: CellRange | null
    currentCell: CellPosition
    selectedRows: number[]
    selectedColumns: number[]
    selectionMode: SelectionMode
  } {
    return {
      selectedCell: this.selectedCell,
      selectionRange: this.selectionRange,
      currentCell: this.currentCell,
      selectedRows: Array.from(this.selectedRows),
      selectedColumns: Array.from(this.selectedColumns),
      selectionMode: this.selectionMode
    }
  }

  // 销毁
  destroy(): void {
    // 停止自动滚动
    this.stopAutoScroll()
    
    // 清理滚动条拖动的节流定时器
    if (this.scrollbarDragThrottle) {
      clearTimeout(this.scrollbarDragThrottle)
      this.scrollbarDragThrottle = null
    }
    
    // 移除画布事件监听
    this.canvas.removeEventListener('mousedown', this.handleMouseDown.bind(this))
    this.canvas.removeEventListener('mousemove', this.handleMouseMove.bind(this))
    this.canvas.removeEventListener('mouseup', this.handleMouseUp.bind(this))
    this.canvas.removeEventListener('mouseleave', this.handleMouseLeave.bind(this))
    this.canvas.removeEventListener('dblclick', this.handleDoubleClick.bind(this))
    this.canvas.removeEventListener('contextmenu', this.handleContextMenu.bind(this))
    this.canvas.removeEventListener('wheel', this.handleWheel.bind(this))
    this.canvas.removeEventListener('keydown', this.handleKeyDown.bind(this))
    
    // 移除文档级事件监听
    if ((this as any).documentMouseUp) {
      document.removeEventListener('mouseup', (this as any).documentMouseUp)
      delete (this as any).documentMouseUp
    }
    if ((this as any).documentMouseMove) {
      document.removeEventListener('mousemove', (this as any).documentMouseMove)
      delete (this as any).documentMouseMove
    }
    
    // 清理提示框
    if (this.resizeTooltip) {
      this.resizeTooltip.remove()
      this.resizeTooltip = null
    }
    
    // 清理事件处理器
    this.eventHandlers.clear()
  }

  // 处理滚轮
  private handleWheel(e: WheelEvent): void {
    e.preventDefault()
    
    // 如果正在编辑，先结束编辑
    if (this.isEditing) {
      this.endEdit(true)
      return
    }
    
    // 计算滚动方向和距离
    const deltaX = e.shiftKey ? e.deltaY : e.deltaX
    const deltaY = e.shiftKey ? 0 : e.deltaY
    
    // 更新滚动位置
    if (this.scrollManager.handleWheel(deltaX, deltaY)) {
      // 触发重绘
      this.requestRender()
    }
  }

  // 处理键盘按下
  private handleKeyDown(e: KeyboardEvent): void {
    // 如果正在编辑，不处理导航键
    if (this.isEditing) {
      if (e.key === 'Enter' || e.key === 'Tab') {
        this.endEdit(true)
        if (e.key === 'Tab') {
          e.preventDefault()
          this.moveCursor(0, e.shiftKey ? -1 : 1)
        }
      } else if (e.key === 'Escape') {
        this.endEdit(false)
      }
      return
    }
    
    // 导航键
    switch (e.key) {
      case 'Escape':
        e.preventDefault()
        // 清除剪贴板数据
        if (this.clipboardData) {
          this.clipboardData = null
          this.requestRender()
        }
        break
      case 'ArrowUp':
        e.preventDefault()
        this.moveCursor(-1, 0, e.shiftKey)
        break
      case 'ArrowDown':
        e.preventDefault()
        this.moveCursor(1, 0, e.shiftKey)
        break
      case 'ArrowLeft':
        e.preventDefault()
        this.moveCursor(0, -1, e.shiftKey)
        break
      case 'ArrowRight':
        e.preventDefault()
        this.moveCursor(0, 1, e.shiftKey)
        break
      case 'Home':
        e.preventDefault()
        if (e.ctrlKey) {
          this.moveTo(0, 0, e.shiftKey)
        } else {
          this.moveTo(this.currentCell.row, 0, e.shiftKey)
        }
        break
      case 'End':
        e.preventDefault()
        if (e.ctrlKey) {
          this.moveTo(this.dataManager.getRowCount() - 1, this.dataManager.getColumnCount() - 1, e.shiftKey)
        } else {
          this.moveTo(this.currentCell.row, this.dataManager.getColumnCount() - 1, e.shiftKey)
        }
        break
      case 'PageUp':
        e.preventDefault()
        this.pageUp(e.shiftKey)
        break
      case 'PageDown':
        e.preventDefault()
        this.pageDown(e.shiftKey)
        break
      case 'Enter':
        e.preventDefault()
        if (this.currentCell) {
          this.startEdit(this.currentCell)
        }
        break
      case 'Delete':
        e.preventDefault()
        this.deleteSelectedCells()
        break
      case 'F2':
        e.preventDefault()
        if (this.currentCell) {
          this.startEdit(this.currentCell)
        }
        break
    }
    
    // 快捷键
    if (e.ctrlKey || e.metaKey) {
      switch (e.key) {
        case 'a':
        case 'A':
          e.preventDefault()
          this.selectAll()
          break
        case 'c':
        case 'C':
          e.preventDefault()
          this.copy()
          break
        case 'v':
        case 'V':
          e.preventDefault()
          this.paste()
          break
        case 'x':
        case 'X':
          e.preventDefault()
          this.cut()
          break
        case 'z':
        case 'Z':
          e.preventDefault()
          if (e.shiftKey) {
            this.redo()
          } else {
            this.undo()
          }
          break
        case 'y':
        case 'Y':
          e.preventDefault()
          this.redo()
          break
      }
    }
    
    this.emit(EventType.KeyDown, e)
  }

  // 撤销
  private undo(): void {
    if (this.dataManager.undo()) {
      this.requestRender()
    }
  }

  // 重做
  private redo(): void {
    if (this.dataManager.redo()) {
      this.requestRender()
    }
  }

  // 获取剪贴板数据（供渲染器使用）
  getClipboardData(): { cells: CellPosition[]; isCut: boolean } | null {
    if (!this.clipboardData) return null
    return {
      cells: this.clipboardData.cells,
      isCut: this.clipboardData.isCut
    }
  }

  // 选择行
  selectRow(row: number, extend: boolean = false): void {
    if (!extend) {
      this.selectedRows.clear()
      this.selectedColumns.clear()
      this.selectedCell = null
      this.selectionRange = null
      this.selectedCells.clear()
    }
    
    this.selectedRows.add(row)
    this.selectionMode = SelectionMode.Row
    this.lastSelectedRow = row
    
    this.emit(EventType.SelectionChange, {
      selectedCells: [],
      selectedRows: Array.from(this.selectedRows),
      selectedColumns: [],
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }
  
  // 选择列
  selectColumn(col: number, extend: boolean = false): void {
    if (!extend) {
      this.selectedRows.clear()
      this.selectedColumns.clear()
      this.selectedCell = null
      this.selectionRange = null
      this.selectedCells.clear()
    }
    
    this.selectedColumns.add(col)
    this.selectionMode = SelectionMode.Column
    this.lastSelectedColumn = col
    
    this.emit(EventType.SelectionChange, {
      selectedCells: [],
      selectedRows: [],
      selectedColumns: Array.from(this.selectedColumns),
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }
  
  // 清除所有选择
  clearAllSelection(): void {
    this.selectedCell = null
    this.selectionRange = null
    this.selectedCells.clear()
    this.selectedRows.clear()
    this.selectedColumns.clear()
    this.selectionMode = SelectionMode.Cell
    
    this.emit(EventType.SelectionChange, {
      selectedCells: [],
      selectedRows: [],
      selectedColumns: [],
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }

  // 更新悬停状态
  private updateHoverState(x: number, y: number): void {
    const oldHoveredCell = this.hoveredCell
    const oldHoveredRow = this.hoveredRow
    const oldHoveredColumn = this.hoveredColumn
    
    // 获取当前悬停的单元格
    const cell = this.getCellByPosition(x, y)
    this.hoveredCell = cell
    
    // 获取悬停的行
    const row = this.scrollManager.getRowByY(y)
    this.hoveredRow = row
    
    // 获取悬停的列
    const adjustedX = x - (this.showRowNumber ? this.rowNumberWidth : 0)
    const col = this.scrollManager.getColumnByX(adjustedX)
    this.hoveredColumn = col
    
    // 如果悬停状态改变，请求重新渲染
    if (oldHoveredCell?.row !== cell?.row || oldHoveredCell?.col !== cell?.col ||
        oldHoveredRow !== row || oldHoveredColumn !== col) {
      
      // 触发悬停状态改变事件
      this.emit('hover-change' as EventType, {
        hoveredCell: this.hoveredCell,
        hoveredRow: this.hoveredRow,
        hoveredColumn: this.hoveredColumn
      })
      
      this.requestRender()
    }
  }
  
  // 更新鼠标样式
  private updateCursor(x: number, y: number): void {
    // 检查是否在填充柄上
    if (this.isOnFillHandle(x, y)) {
      this.canvas.style.cursor = 'crosshair'
      return
    }
    
    // 检查是否在滚动条上并更新悬停状态
    const scrollbarType = this.getScrollbarType(x, y)
    if (scrollbarType) {
      this.canvas.style.cursor = 'default'
      
      // 更新渲染器的滚动条悬停状态
      if (this.renderer && typeof this.renderer.setScrollbarHoverState === 'function') {
        this.renderer.setScrollbarHoverState(
          scrollbarType === 'vertical',
          scrollbarType === 'horizontal'
        )
        this.requestRender()
      }
      return
    } else {
      // 清除滚动条悬停状态
      if (this.renderer && typeof this.renderer.setScrollbarHoverState === 'function') {
        this.renderer.setScrollbarHoverState(false, false)
        this.requestRender()
      }
    }
    
    // 检查是否在行边界上（调整行高）
    const rowResizeHandle = this.getRowResizeHandle(x, y)
    if (rowResizeHandle >= 0) {
      this.canvas.style.cursor = 'row-resize'
      // 显示当前行高
      const currentHeight = this.rowHeights.get(rowResizeHandle) || this.defaultRowHeight
      this.updateResizeTooltip(x, y, `行高: ${Math.round(currentHeight)}px`)
      return
    }
    
    // 检查是否在列边界上（调整列宽）
    const colResizeHandle = this.getColumnResizeHandle(x, y)
    if (colResizeHandle >= 0) {
      this.canvas.style.cursor = 'col-resize'
      // 显示当前列宽
      const columns = this.dataManager['columns']
      const currentWidth = columns[colResizeHandle].width || 100
      this.updateResizeTooltip(x, y, `列宽: ${Math.round(currentWidth)}px`)
      return
    }
    
    // 隐藏提示框（当不在调整边界时且不在调整过程中）
    if (!this.isResizingColumn && !this.isResizingRow) {
      this.hideResizeTooltip()
    }
    
    // 检查是否在左上角（全选按钮）
    if (this.showRowNumber && x < this.rowNumberWidth && y < this.scrollManager.getHeaderHeight()) {
      this.canvas.style.cursor = 'pointer'
      return
    }
    
    // 检查是否在行号或列头上
    if (this.isOnRowHeader(x, y)) {
      this.canvas.style.cursor = 'pointer'
      return
    }
    
    if (this.isOnColumnHeader(x, y)) {
      // 列头上显示默认光标，因为现在用于选择列
      this.canvas.style.cursor = 'default'
      return
    }
  }

  // 自动调整列宽以适应内容
  private autoFitColumn(columnIndex: number): void {
    const columns = this.dataManager['columns']
    const column = columns[columnIndex]
    
    // 计算列内容的最大宽度
    let maxContentWidth = 0
    
    // 计算列标题宽度
    const ctx = this.canvas.getContext('2d')
    if (ctx) {
      ctx.font = `bold ${this.defaultRowHeight * 0.5}px Arial`
      const titleWidth = ctx.measureText(column.title).width + 20 // 加上padding
      maxContentWidth = Math.max(maxContentWidth, titleWidth)
      
      // 计算前100行的内容宽度（性能考虑）
      ctx.font = `${this.defaultRowHeight * 0.5}px Arial`
      const rowCount = Math.min(100, this.dataManager.getRowCount())
      
      for (let row = 0; row < rowCount; row++) {
        const value = this.dataManager.getCellValue(row, column.field)
        const displayValue = column.formatter ? column.formatter(value) : String(value || '')
        const contentWidth = ctx.measureText(displayValue).width + 20
        maxContentWidth = Math.max(maxContentWidth, contentWidth)
      }
    }
    
    // 设置新宽度（在最小和最大范围内）
    const minWidth = column.minWidth || 60
    const maxWidth = column.maxWidth || 600
    const newWidth = Math.max(minWidth, Math.min(maxContentWidth, maxWidth))
    
    column.width = newWidth
    
    // 更新滚动管理器
    this.scrollManager.setDataInfo(this.dataManager.getRowCount(), columns)
    
    this.emit(EventType.ColumnResize, {
      column: columnIndex,
      width: newWidth
    })
    
    this.requestRender()
  }

  // 验证并修正当前单元格位置
  validateCurrentCell(): void {
    const rowCount = this.dataManager.getRowCount()
    const colCount = this.dataManager.getColumnCount()
    
    // 如果表格为空，重置currentCell
    if (rowCount === 0 || colCount === 0) {
      this.currentCell = { row: 0, col: 0 }
      this.selectedCell = null
      this.selectionRange = null
      return
    }
    
    // 确保currentCell在有效范围内
    if (this.currentCell.row >= rowCount) {
      this.currentCell.row = rowCount - 1
    }
    if (this.currentCell.col >= colCount) {
      this.currentCell.col = colCount - 1
    }
    if (this.currentCell.row < 0) {
      this.currentCell.row = 0
    }
    if (this.currentCell.col < 0) {
      this.currentCell.col = 0
    }
    
    // 同时检查selectedCell
    if (this.selectedCell) {
      if (this.selectedCell.row >= rowCount || this.selectedCell.col >= colCount ||
          this.selectedCell.row < 0 || this.selectedCell.col < 0) {
        this.selectedCell = null
        this.selectionRange = null
      }
    }
  }

  // 处理列变化
  handleColumnsChange(): void {
    // 立即验证 currentCell
    this.validateCurrentCell()
    
    // 清除可能无效的选择
    const colCount = this.dataManager.getColumnCount()
    
    // 清除超出范围的列选择
    const validColumns = new Set<number>()
    this.selectedColumns.forEach(col => {
      if (col >= 0 && col < colCount) {
        validColumns.add(col)
      }
    })
    this.selectedColumns = validColumns
    
    // 检查并调整范围选择
    if (this.selectionRange) {
      const maxCol = colCount - 1
      if (this.selectionRange.start.col > maxCol || this.selectionRange.end.col > maxCol) {
        this.selectionRange = null
        this.selectedCell = null
      }
    }
    
    // 如果选择模式是列选择但没有有效列，切换到单元格模式
    if (this.selectionMode === SelectionMode.Column && this.selectedColumns.size === 0) {
      this.selectionMode = SelectionMode.Cell
    }
    
    // 触发选择变化事件
    this.emit(EventType.SelectionChange, {
      selectedCells: this.getSelectedCells(),
      selectedRange: this.selectionRange,
      selectedRows: Array.from(this.selectedRows),
      selectedColumns: Array.from(this.selectedColumns),
      selectionMode: this.selectionMode
    } as SelectionChangeEvent)
    
    this.requestRender()
  }
  
  // 设置渲染器引用
  setRenderer(renderer: any): void {
    this.renderer = renderer
  }

  // 设置表格实例引用
  setTable(table: any): void {
    this.table = table
  }
  
  // 确保单元格完全可见
  private ensureCellVisible(row: number, col: number): void {
    const columns = this.dataManager['columns']
    const column = columns[col]
    const cellWidth = column.width || 100
    const cellHeight = this.scrollManager.getRowHeight(row)
    
    const scrollPos = this.scrollManager.getScrollPosition()
    const containerSize = this.scrollManager.getContainerSize()
    const headerHeight = this.scrollManager.getHeaderHeight()
    const rowNumberWidth = this.showRowNumber ? this.rowNumberWidth : 0
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    
    // 添加一些边距，确保单元格周围有一些空间
    const margin = 5
    
    // 计算单元格的实际位置（相对于内容区域，不是视口）
    let cellTop = 0
    for (let i = 0; i < row; i++) {
      cellTop += this.scrollManager.getRowHeight(i)
    }
    
    let cellLeft = 0
    for (let i = 0; i < col; i++) {
      cellLeft += (columns[i].width || 100)
    }
    
    // 计算可视区域（考虑表头、行号列和滚动条）
    const visibleLeft = margin
    const visibleTop = headerHeight + margin
    const visibleRight = containerSize.width - (scrollbarInfo.vertical.visible ? scrollbarWidth : 0) - margin
    const visibleBottom = containerSize.height - (scrollbarInfo.horizontal.visible ? scrollbarWidth : 0) - margin
    const visibleWidth = visibleRight - visibleLeft - rowNumberWidth
    const visibleHeight = visibleBottom - visibleTop
    
    // 计算单元格在内容区域的边界
    const cellRight = cellLeft + cellWidth
    const cellBottom = cellTop + cellHeight
    
    let newScrollLeft = scrollPos.scrollLeft
    let newScrollTop = scrollPos.scrollTop
    
    // 水平滚动调整
    if (cellLeft < scrollPos.scrollLeft + margin) {
      // 单元格在左边界外
      newScrollLeft = Math.max(0, cellLeft - margin)
    } else if (cellRight > scrollPos.scrollLeft + visibleWidth) {
      // 单元格在右边界外
      const contentSize = this.scrollManager.getContentSize()
      const maxScrollLeft = Math.max(0, contentSize.width - containerSize.width)
      newScrollLeft = Math.min(
        cellRight - visibleWidth + margin,
        maxScrollLeft
      )
    }
    
    // 垂直滚动调整
    if (cellTop < scrollPos.scrollTop + margin) {
      // 单元格在上边界外
      newScrollTop = Math.max(0, cellTop - margin)
    } else if (cellBottom > scrollPos.scrollTop + visibleHeight) {
      // 单元格在下边界外
      const contentSize = this.scrollManager.getContentSize()
      const maxScrollTop = Math.max(0, contentSize.height - containerSize.height)
      newScrollTop = Math.min(
        cellBottom - visibleHeight + margin,
        maxScrollTop
      )
    }
    
    // 执行滚动
    if (newScrollLeft !== scrollPos.scrollLeft || newScrollTop !== scrollPos.scrollTop) {
      this.scrollManager.setScrollPosition(newScrollLeft, newScrollTop)
      this.requestRender()
    }
  }
} 